﻿

using Grpc.Core;
using InfluxDB.Client.Api.Domain;
using IotClientService.Models.Lg;
using IotClientService.Services;
using IotContract.Enums;
using IotContract.Models.Clients.Hks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Intrinsics.X86;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;

namespace IotClientService.Handles.lgs;
/// <summary>
/// 筛选机处理
/// </summary>
///
public class LgHandleSel : LgHandleBase
{
    public LgHandleSel(ILgApiService lgCallApiService) : base(lgCallApiService)
    {
    }

    public override IotEquipType EquipType { get; set; } = IotEquipType.SEL;
    /// <summary>
    /// 处理消息 
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public override async Task<bool> HandleMsg(LgMsgInfo msg)
    {
        string replyCmd = string.Empty;
        switch (msg.Command)
        {
            // 作业实处理Data报告，上位机每次挑选NG电池报告 
            case "901":
                replyCmd = "902";
               await Handle901(msg, replyCmd);
                break;
            // 作业开始/结束报告，上位机报告
            case "905":
                replyCmd = "906";
              await  Handle905(msg, replyCmd);
                break;
            // 设备状态报告指示回应，主动发送909获取状态
            case "910":
              await  Handle910(msg, "910");
                // send 833 

                break;
            // 设备状态报告，待机状态变设备运行状态或设备运行状态变设备待机
            case "913":
               await Handle913(msg, "913");
                break;
            // 作业mode报告，设备模式切换时告知，如自动模式切换手动模式，反过来也是一样
            case "917":
                replyCmd = "918";
               await Handle917(msg, replyCmd);
                break;
            // 通信状态报告邀请，上位机和 FMS 相互连接状态
            case "925":
                replyCmd = "926";
               await Handle925(msg, replyCmd);
                break;
            // 通信状态报告回应
            case "926":
               await Handle926(msg, "926");
                break;
            // Tray Load报告 上位机告知 FMS 托盘到达
            case "933":
                replyCmd = "934";
               await Handle933(msg, replyCmd);
                break;
            // 托盘出库完成报告，上位机告知托盘要出库
            case "937":
                replyCmd = "938";
               await Handle937(msg, replyCmd);
                break;
            // 未知命令,错误
            case "981":
               await Handle981(msg, "981");
                break;
            // 设备Trouble报告，设备发生异常告知FMS
            case "985":
               await Handle985(msg, "985");
                break;
            // NG List邀请，上位机邀请 FMS 发送 NG 电池位置
            case "801":
                replyCmd = "802";
               await Handle801(msg, replyCmd);
                break;
            case "804":
                replyCmd = "805";
               await Handle804(msg, replyCmd);
                break;
           
            // 设置时间指示
            case "999":
               await Handle999(msg, replyCmd);
                break;
            default:
                // send 981
               await Handle981(msg, "981");
                break;
        }

        Api.LogData("ReplyCommand", replyCmd);
        return true;
    }
    /// <summary>
    /// 作业实处理Data报告，上位机每次挑选NG电池报告 ,先始终返回OK，不作处理
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle901(LgMsgInfo msg, string replyCmd)
    {
        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };
        // 托盘码
        string tray = msg.Message.Substring(18, 10);
        // 电芯挑出位置 01-48
        string location = msg.Message.Substring(38, 2);
        // R  E
        string type = msg.Message.Substring(40, 1);

        Equip.Action = location;
        var ret = 0;
        var result= await Api.CommitSelResult(new LgSelResultRequest
        {
            EquipNum=Equip.Num,
            EquipType = this.EquipType,
            ProgramType = Equip.ProgramType,
            Tray = tray,
            Location = location,
            Type = type
        });
        if (!result.Success)
        {
            Equip.ExMessage = result.Message;
            ret = 1;
        }
        else
        {
            ret = result.Result?.Ret ?? 1;
        }
        if (ret == 1)
        {
            msg.Body = ret.ToString();
            await Handle981(msg, "981");
            return;
        }

        var ngCode = result.Result?.NgCodes?.FirstOrDefault() ?? "0000";

        string flag = $"{ret}{ngCode}";

        // 19017 没有作业开始的托盘
        // 19018 不是不良
        // 19000 处理错误


        sendMsg.Body = $"{flag}{type}";
        sendMsg.IsSend = true;
        InvokeSend(sendMsg);


    }
    /// <summary>
    /// 验证
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle804(LgMsgInfo msg,string replyCmd)
    {
       

        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };
        sendMsg.IsSend = true;
        InvokeSend(sendMsg);
    }

    /// <summary>
    /// 作业开始/结束报告
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle905(LgMsgInfo msg, string replyCmd)
    {
        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };
       
        // 托盘
        string tray = msg.Message.Substring(18, 10);

        // S:作业开始  E:作业完成
        string status = msg.Message.Substring(38, 1);

        Equip.Action = status;
        // 托盘位置No
        var location = msg.Message.Substring(39, 1);

        // 一共4个位置
        Equip.ExplainData= location;

        var result= await Api.CommitSelReport(new Models.Lg.Remote.LgSelReportRequest
        {
            EquipNum=Equip.Num,
            EquipType = this.EquipType,
            ProgramType = Equip.ProgramType,
            Tray = tray,
            Status = status,
            TrayLocation = location
        });
        int ret = 0;

        if (!result.Success)
        {
            Equip.ExMessage = result.Message;
            ret = 1;
        }
        else
        {
            ret = result.Result?.Ret ?? 1;
        }
        if (ret == 1)
        {
            msg.Body = ret.ToString();
            await Handle981(msg, "981");
            return;
        }
        var ng = result.Result?.NgCodes?.FirstOrDefault() ?? "0000";
        sendMsg.Body = $"{ret}{status}{ng}";
        sendMsg.IsSend = true;
        Equip.Remark = $"tray:{tray}-{status}";
        InvokeSend(sendMsg);

    }

    /// <summary>
    /// Tray Load报告，下发挑选位置和电池码
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle933(LgMsgInfo msg, string replyCmd)
    {
        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };

       
        
        // 托盘
        var tray = msg.Message.Substring(18, 10);
        Equip.Obj = tray;

        
        // 1，2 （作业托盘）， 3，4 （空托盘）OCV位置一个ABB有4个位置，作业区位置2个，装NG电池的空盘位2个
        var status = msg.Message.Substring(38, 1);

        Equip.ExplainData = status;

        var result= await Api.CommitSelEnter(new Models.Lg.Remote.LgSelReportRequest
        {
            EquipNum=Equip.Num,
            EquipType = this.EquipType,
            ProgramType = Equip.ProgramType,
            Tray = tray,
            TrayLocation = status
        });
        // 0:ok 1:ng  2:bypass 3:托盘内电池最大NG数量超出设定值，需协商（不良率超过20%不挑选，直接排出到异常排出口等
        int ret = 0;
        if (!result.Success)
        {
            Equip.ExMessage = result.Message;
            ret = 1;
        }
        else
        {
            ret = result.Result?.Ret ?? 1;
        }
        if (ret == 1)
        {
            msg.Body = ret.ToString();
            await Handle981(msg, "981");
            return;
        }

        Equip.Remark = $"tray load:{tray}-{status}";

        #region 传输body
       
        // 0001-9999NG
        var ng = result.Result?.NgCodes?.FirstOrDefault() ?? "0000";
        var trayId = tray.PadRight(20, '0');
        #endregion
        // 没有ng电芯传2
        sendMsg.Body = $"{ret}{ng}{trayId}";
        sendMsg.IsSend = true;
        InvokeSend(sendMsg);
    }
    /// <summary>
    /// 托盘出库完成报告
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle937(LgMsgInfo msg, string replyCmd)
    {
        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };
        // 托盘
        var tray = msg.Message.Substring(18, 10);
        // 1，2 （作业托盘）， 3，4 （ 空托盘 ）
        var position = msg.Message.Substring(38, 1);

        Equip.ExplainData = position;

        Equip.Remark = $"tray:{tray}-{position} out";

        
        Equip.Obj = "";

        var result=  await Api.CommitSelOut(new Models.Lg.Remote.LgSelReportRequest
        {
            EquipNum=Equip.Num,
            EquipType = this.EquipType,
            ProgramType = Equip.ProgramType,
            Tray = tray,
            TrayLocation = position
        });
        // 0:ok 1:ng
        int ret = 0;
        if (!result.Success)
        {
            Equip.ExMessage = result.Message;
            ret = 1;
        }
        else
        {
            ret = result.Result?.Ret ?? 1;
        }
        if (ret == 1)
        {
            msg.Body = ret.ToString();
            await Handle981(msg, "981");
            return;
        }
        #region 传输body

        // 0001-9999NG
        var ng = result.Result?.NgCodes?.FirstOrDefault() ?? "0000";

        // 937不是空托盘
        // 9002没有获取tray信息

        #endregion
        sendMsg.Body = $"{ret}{ng}{tray.PadRight(20,'0')}";
        sendMsg.IsSend = true;
        InvokeSend(sendMsg);
    }
  
    /// <summary>
    /// NG List邀请，上位机邀请 FMS 发送 NG 电池位置
    /// </summary>
    /// <param name="msg"></param>
    /// <param name="replyCmd"></param>
    private async Task Handle801(LgMsgInfo msg, string replyCmd)
    {
        var sendMsg = new LgMsgInfo
        {
            Direction = 0,
            ObjID = msg.ObjID,
            HasMsg = 0,
            SeqNo = msg.SeqNo,
            Command = replyCmd,

        };
        // 托盘
        string tray = msg.Message.Substring(18, 10);

        var result=  await Api.GetSelRecipe(new Models.Lg.Remote.LgTrayReportRequest
        {
            EquipNum=Equip.Num,
            EquipType = this.EquipType,
            ProgramType = Equip.ProgramType,
            Tray = tray
        });
        if(!result.Success)
        {
            Equip.ExMessage= result.Message; 
            msg.Body ="1";
            await Handle981(msg, "981");
            return;
        }
       
        // 查询数据

        #region 数据构造
        // 电池数量 16或者48
        var cellCount = result.Result?.CellCount.ToString()??"00";
        // 长度16  0:没有电池 1:ok 2:ng  3:  4:  7:  9
        var ngSum = result.Result?.CellJudge??"0000000000000000";
        // 不良托盘位置 1:ocv1-3  2:ocv2-4 
        var position = result.Result?.TrayPosition.ToString()??"0";

        
        sendMsg.Body = $"{cellCount}{ngSum}{position}";

        sendMsg.IsSend = true;

        InvokeSend(sendMsg);

        #endregion
    }

  
}
